package com.cqupt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cqupt.service.PortService;
import com.cqupt.utils.*;
import com.cqupt.utils.TextUtils;
import org.springframework.stereotype.Service;

import java.sql.SQLOutput;
import java.util.*;

@Service
public class PortServiceImpl implements PortService {

    /**
     * 获取所有的SNMP设备
     *
     * @return 获取所有的SNMP设备
     */
    @Override
    public List<Map<String, Object>> getAllSNMPDevices() {
        final String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>() {{
            put("jsonrpc", "2.0");
            put("method", "hostinterface.get");
            put("id", 1);
            put("auth", token);
            put("params", new HashMap<String, Object>() {{
                put("output", new String[]{"host"});
                put("filter", new HashMap<String, Object>() {{
                    put("type", 2);
                }});
                put("selectHosts", new String[]{"host"});
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resultList = (List<Map<String, Object>>) responseMap.get("result");
        for (Map<String, Object> map : resultList) {
            TextUtils.putInnerValueToOutside(map, "hosts", new String[]{"host", "hostid"});
        }
        return resultList;
    }

    /**
     * 获取所有端口
     * @param hostid 主机 id
     * @return
     */
    @Override
    public Map<String,Map<String,Object>> getAllPort(String hostid) {
        final String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>() {{
            put("jsonrpc", "2.0");
            put("method", "application.get");
            put("id", 1);
            put("auth", token);
            put("params", new HashMap<String, Object>() {{
                put("output", "extend");
                put("hostids", hostid);
                put("filter", new HashMap<String, Object>() {{
                    put("flags", 4);
                }});
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resultList = (List<Map<String, Object>>) responseMap.get("result");
        for (Map<String, Object> map : resultList) {
            System.out.println("before"+map);
        }
        Map<String,Map<String,Object>> returnMap = new HashMap<>();
//      端口数为 0
        if (resultList.size() == 0){
            returnMap.put("info",new HashMap<String, Object>(){{put("未检测到端口","未检测到端口，请配置自动发现规则");}});
        }

        for (Map<String, Object> map : resultList) {
//          端口名称
            String portName = (String) map.get("name");
//          端口号
            String port = (String) map.get("applicationid");
//          封装端口信息
            Map<String, Object> info = getPortInfo(hostid, port);
            returnMap.put(portName,info);
        }
        System.out.println("CX:"+returnMap);
        return returnMap;
    }

    /**
     * 获取端口流量的利用率
     * @param hostId 主机 id
     * @param applicationid 端口号
     * @return
     */
    public static Map<String, Object> getPortInfo(String hostId, String applicationid) {
        final String token = APIUtils.getToken();
        Map<String, Object> paramsMap = new HashMap<String, Object>() {{
            put("jsonrpc", "2.0");
            put("method", "item.get");
            put("id", 1);
            put("auth", token);
            put("params", new HashMap<String, Object>() {{
                put("output", new String[]{"lastvalue", "name"});
                put("hostids", hostId);
                put("applicationids", applicationid);
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resultList = (List<Map<String, Object>>) responseMap.get("result");
        Map<String,Object> returnMap = new HashMap<>();

//      丢包率（入）
        Map<String, Object> inDiscardedPackets = null;
//      错包率（入）
        Map<String, Object> inErrorsPackets = null;
//      端口带利用率（入）
        Map<String, Object> inBits = null;
//      丢包率（出）
        Map<String, Object> outDiscardedPackets = null;
//      错包率（出）
        Map<String, Object> outErrorsPackets = null;
//      端口带利用率（出）
        Map<String, Object> outBits = null;
//      端口流量
        Map<String, Object> speed = null;
//      端口状态
        Map<String, Object> status = null;

        Iterator<Map<String, Object>> iterator = resultList.iterator();
        while (iterator.hasNext()) {
            Map<String, Object> map = iterator.next();
            String name = map.get("name").toString();
            if (name.contains("Duplex status")) {
                iterator.remove();
            } else if (name.contains("Inbound packets discarded")) {
                inDiscardedPackets = map;
            } else if (name.contains("Inbound packets with errors")) {
                inErrorsPackets = map;
            } else if (name.contains("Bits received")) {
                inBits = map;
            } else if (name.contains("Outbound packets discarded")) {
                outDiscardedPackets = map;
            } else if (name.contains("Outbound packets with errors")) {
                outErrorsPackets = map;
            } else if (name.contains("Bits sent")) {
                outBits = map;
            } else if (name.contains("Speed")) {
                speed = map;
            } else if (name.contains("Operational status")) {
                status = map;
            }
        }
        if(speed == null){
            returnMap.put("speed","0");
        }else {
           returnMap.put("speed",speed.get("lastvalue"));
        }

        if (status == null){
            returnMap.put("status","无监控端口的监控项");
        }else
            getPortStatus(status,returnMap);  //获取端口状态
        if (null == inErrorsPackets){
            returnMap.put("Inboundpacketswitherrors","0");
        }else
            getRateOfSome(inErrorsPackets, inBits,returnMap); //获取错包率（入）
        if (outErrorsPackets == null){
            returnMap.put("Outboundpacketswitherrors","0");
        }else
            getRateOfSome(outErrorsPackets, outBits,returnMap); //获取错包率（出）
        if (inDiscardedPackets == null){
            returnMap.put("Inboundpacketsdiscarded","0");
        }else
            getRateOfSome(inDiscardedPackets, inBits,returnMap); //获取去丢包率（入）
        if (outDiscardedPackets == null){
            returnMap.put("Outboundpacketsdiscarded","0");
        }else
            getRateOfSome(outDiscardedPackets, outBits,returnMap); //获取丢包率（出）
        if (inBits == null){
            returnMap.put("Bitssent","0");
        }else
            getRateOfSome(inBits, speed,returnMap);    //获取端口带利用率（入）
        if (outBits == null){
            returnMap.put("Bitsreceived","0");
        }else
            getRateOfSome(outBits, speed,returnMap);//获取端口带利用率（出）

        return returnMap;
    }

    /**
     * 获取交换机的序列号和温度
     *
     * @param hostId 设备ID
     */
    @Override
    public Map<String,String> getInfomtionByhostId(String hostId) {
        //拿API的token
        final String token = APIUtils.getToken();
        //获取序列号，温度，mac地址的硬件信息，软件版本号，补丁文件版本，运行时间，设备型号
        List<Map<String, Object>> temperature = getItemsByName(token, hostId, "Temperature");//温度
        List<Map<String, Object>> serialNum = getItemsByName(token, hostId, "Hardware serial number");//序列号
//        List<Map<String, Object>> systemMac = getItemsByName(token, hostId, "hwStackSystemMac");
        List<Map<String, Object>> SoftwareRev = getItemsByName(token, hostId, "Operating system");//软件版本
//        List<Map<String, Object>> PatchVersion = getItemsByName(token, hostId, "hwPatchVersion");
//        List<Map<String, Object>> UpTime = getItemsByName(token, hostId, "sysUpTime");
        List<Map<String, Object>> PhysicalDescr = getItemsByName(token, hostId, "Hardware model name");//产品型号
        List<Map<String, Object>> CPUutilization = getItemsByName(token, hostId, "CPU utilization");//CPU利用率
        List<Map<String, Object>> Memoryutilization = getItemsByName(token, hostId, "Memory utilization");//内存利用率
        List<Map<String, Object>> HardwareVersion = getItemsByName(token, hostId, "Hardware version");//硬件版本
        List<Map<String, Object>> listresponMap = new ArrayList<Map<String, Object>>();
        //将硬件信息放入listmap
        listresponMap.add(temperature.get(0));
        listresponMap.add(serialNum.get(0));
//        listresponMap.add(systemMac.get(0));
        listresponMap.add(SoftwareRev.get(0));
//        listresponMap.add(PatchVersion.get(0));
//        Map<String, Object> time = UpTime.get(0);
//        DateUtils.formatListDate(time,"lastvalue");
//        listresponMap.add(time);
        listresponMap.add(PhysicalDescr.get(0));
        listresponMap.add(CPUutilization.get(0));
        listresponMap.add(Memoryutilization.get(0));
        listresponMap.add(HardwareVersion.get(0));

//        System.out.println("implsnmp:"+listresponMap.toString());
        Map<String,String> map = new HashMap<>();
        map = packageSnmp(listresponMap);
        return map;
    }

    /**
     * 对SNMP获得的基本监控项进行重新封装
     * @param list
     * @return
     */
    public Map<String,String> packageSnmp(List<Map<String, Object>> list){
        Map<String,String> map = new HashMap<>();
        map.put("Temperature","无数据");
        map.put("Hardware_serial_number","无数据");
        map.put("Operating_system","无数据");
        map.put("Hardware_model_name","无数据");
        map.put("CPU_utilization","无数据");
        map.put("Memory_utilization","无数据");
        map.put("Hardware_version","无数据");

        for (int i = 0; i < list.size(); i++) {
            if(list.get(i).size()!=0){
                String name = (String) list.get(i).get("name");
                String value = (String) list.get(i).get("lastvalue");
                // name = name.replace(/\s/g,"");
//                map.set(name, list[i].lastvalue);
                if (name.contains("Temperature") ){
                    map.put("Temperature",value);//将温度放到map
                } else if (name.contains("Hardware serial number")){
                    map.put("Hardware_serial_number",value);//将序列号放到map
                } else if (name.contains("Operating system") ){
                    map.put("Operating_system",value);//将软件版本号放到map
                } else if (name.contains("Hardware model name")){
                    map.put("Hardware_model_name",value);//将产品型号放到map
                } else if (name.contains("CPU utilization")){
                    map.put("CPU_utilization",value);//将cpu利用率放到map
                } else if (name.contains("Memory utilization")){
                    map.put("Memory_utilization",value);//将内存利用率放到map
                } else if (name.contains("Hardware version") ){
                    map.put("Hardware_version",value);//将温度放到map
                }
            }
        }
        return map;
    }

    /**
     * 获取监控设备hostId和监控项的名称获取硬件信息
     *
     * @param token
     * @param hostId  主机 id
     * @param name   监控项名称
     */
    public List<Map<String, Object>> getItemsByName(final String token, final String hostId, final String name) {
        String[] infoResult = {"hostid", "itemid", "lastvalue", "prevvalue", "name","lastclock"};
        Map<String, Object> paramsMap = new HashMap<String, Object>() {{
            put("jsonrpc", "2.0");
            put("method", "item.get");
            put("id", 1);
            put("auth", token);
            put("params", new HashMap<String, Object>() {{
                put("output", infoResult);
                put("hostids", hostId);
                put("search", new HashMap<String, Object>() {{
                    put("name", name);
                }});
                put("sortfield", "name");
            }});
        }};
        Map<String, Object> responseMap = APIUtils.sendRequest(JSON.toJSONString(paramsMap, SerializerFeature.WriteMapNullValue));
        List<Map<String, Object>> resultList = (List<Map<String, Object>>) responseMap.get("result");

        // 如果返回list为空，则手动存入一个空Map
        if (resultList.size() == 0) {
            resultList.add(new HashMap<>());
        }

        return resultList;
    }

    /**
     * 获取端口状态
     *
     * @param dataMap 转化前的List集合
     */
    public static void getPortStatus(Map<String, Object> dataMap,Map<String,Object> returnMap) {
        TextUtils.transformPortStatus(dataMap,returnMap);
    }

    /**
     * 获取part的利用率
     *
     * @param part  map集合表求谁的利用率
     * @param total map集合表总量
     */
    public static void getRateOfSome(Map<String, Object> part, Map<String, Object> total,Map<String, Object> returnMap) {

        String name = part.get("name").toString();
        int start = name.indexOf(":");
        String key = name.substring(start+1);
        key = key.replaceAll("\\s*", "");
        System.out.println("key"+key);
        if(total == null){
            returnMap.put(key,"0");
        } else {
            String partValue = part.get("lastvalue").toString();
            if ("0".equals(partValue)) {
                returnMap.put(key,"0");
            } else {
                String totalValue = total.get("lastvalue").toString();
                String rate = null;
                if (total.get("name").toString().contains("Speed")) {
                    rate = String.valueOf(Double.parseDouble(partValue) / Double.parseDouble(totalValue)); //part与total中的value都为比特
                } else {
                    rate = String.valueOf(Double.parseDouble(partValue) * 8 / Double.parseDouble(totalValue)); //part为字节，total为比特
                }
                returnMap.put(key,rate);
            }
        }
    }

}
